---------单位表------------
--[[
    PH:0.001
    电压值：0.1mv
    温度：0.1摄氏度
    温度系数0.0001
]]


local sys = require "sys"

---------------------------------------------MODBUS协议带数据保存-----------------------------------------------------
-- 485内存的地址表（带自动保存的（485部分只用动这里就可以其它都是驱动））
Modbus = {
0, -- PH计电压值（int）0.1mv
0, -- PH计读取温度（int，单位0.1摄氏度）2
1, -- 广播地址3
0, -- 0:波特率115200,4
0, -- 温度漂移值,5
0150, -- 温补系数，精度0.01,6
-3000, -- 手动设置温度值0.1摄氏度-3000是，自动设置温度,7
0, -- 校正方式：0:2点校正(使用校正点1,2)  1:3点校正(使用校正点3,4,5),8

7000, -- 校正点1（PH）,9
0, -- 校正点1（电压）,10

14000, -- 校正点2（PH）,11
20000, -- 校正点2（电压）,12




7000, -- 校正点3（PH）,13
0, -- 校正点3（电压）,14

14000, -- 校正点4（PH）,15
20000, -- 校正点4（电压）,16

0, -- 校正点5（PH）,17
-20000, -- 校正点5（电压）,18

-----自动校正，输入已知溶液的ph数值即可，MV数值电极自动记录当前数值-------
0, -- 自动校正点1（PH）,19
0, -- 自动校正点2（PH）,20
0, -- 自动校正点3（PH）,21
0, -- 自动校正点4（PH）,22
0, -- 自动校正点4（PH）,23
---------------------------------y=kx+b---------------------------------------
0,--计算出的PH值24


}
-- 485串口ID
uart_id = 0

-- 支持波特率
BAUD = {115200, 9600}
local function reset()
    fskv.set("modbus", Modbus)
    pm.reboot()
end

-- 额外部分功能（例：广播地址，和波特率设置完成后需要重启）
modbus_switch = {

    [3] = function()
        reset()
    end,
    [4] = function()
        reset()
    end,


    [8] = function()
        reset()
    end,
    [9] = function()
        reset()
    end,
    [10] = function()
        reset()
    end,
    [11] = function()
        reset()
    end,
    [12] = function()
        reset()
    end,
    [13] = function()
        reset()
    end,
    [14] = function()
        reset()
    end,
    [15] = function()
        reset()
    end,
    [16] = function()
        reset()
    end,
    [17] = function()
        reset()
    end,

    [18] = function()
        reset()
    end,
    [19] = function()
        Modbus[9] = Modbus[19]
        Modbus[10] = Modbus[1]
        reset()
    end,
    [20] = function()
        Modbus[11] = Modbus[20]
        Modbus[12] = Modbus[1]
        reset()
    end,
    [21] = function()
        Modbus[13] = Modbus[21]
        Modbus[14] = Modbus[1]
        reset()
    end,
    [22] = function()
        Modbus[15] = Modbus[22]
        Modbus[16] = Modbus[1]
        reset()
    end,
    [23] = function()
        Modbus[17] = Modbus[23]
        Modbus[18] = Modbus[1]
        reset()
    end,
}

--------------------------------------------------------------------------------------------------
function table_leng(t)
    local leng = 0
    for k, v in pairs(t) do
        leng = leng + 1
    end
    return leng;
end
function save_fskv()

    if fskv.init() then
        log.info("fdb", "kv数据库初始化成功")
    end
    local fs = fskv.get("modbus")

    if fs ~= nil then
        if table_leng(Modbus) ~= table_leng(fs) then
            fskv.del("modbus")
            pm.reboot()
        end
        Modbus = fs
    else
        fskv.set("modbus", Modbus)
    end

end
function modbus_send(data)
    local modbus_crc_data = pack.pack('<h', crypto.crc16("MODBUS", data))
    local data_tx = data .. modbus_crc_data
    return data_tx
end
function Modbus_Read(str)
    local idx, crc = pack.unpack(str:sub(-2, -1), "H")
    local temp = str.sub(1, -3)
    if crc == crypto.crc16("MODBUS", temp) then
        local addr, fun, value1, value2 = pack.unpack(temp, ">b2h2")
        if addr == Modbus[3] then
            if fun == 0x06 then
                Modbus[value1] = value2;
                local setUIFunc = switch[value1]
                if setUIFunc then
                    setUIFunc()
                end
                return modbus_send(temp)
            elseif fun == 0x03 then
                local data =
                    (string.format("%02x", addr) .. string.format("%02x", fun) .. string.format("%04x", value2))
                for i = 0, value2 do
                    data = data .. string.format("%04x", Modbus[value1 + i])
                end
                data = data:fromHex()
                return modbus_send(data)
            end
        end

    end
end
--------------------------------------------------------------------------------------------------
--例子串口传入modbus协议
sys.taskInit(function()
    save_fskv()
    print("串口初始化完成")
    uart.setup(uart_id, BAUD[Modbus[4]], 8, 1, uart.None, uart.LSB, 1024)
    uart.on(uart_id, "receive", function(id, len)
        local data = uart.read(id, len)
        local data_tx = Modbus_Read(data)
        uart.write(uart_id, data_tx)
    end)
end)


